package com.xsf.pay.common.config;

import cn.hutool.core.bean.BeanUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * key生成策略
 * @author daimao
 */
@Component("myKeyGenerator")
public class MyKeyGenerator implements KeyGenerator {
    private final static String SEPARATE = ":";
    private final static String PARAM_SEPARATE = ".";
    private final static String PARAM_EQUAL_SEPARATE = "-";
    @NotNull
    @Override
    public Object generate(@NotNull Object target, @NotNull Method method, Object... params) {
        if (params.length == 0) {
            return SimpleKey.EMPTY;
        }
        Object param = params[0];
        try {
            StringBuilder builder = new StringBuilder();
            builder.append(target.getClass().getSimpleName()).append(SEPARATE);
            builder.append(method.getName()).append(SEPARATE);
            if (param instanceof String || param instanceof Integer || param instanceof Long || param instanceof Double || param instanceof Float) {
                builder.append(param);
            } else {
                Map<String, Object> result = BeanUtil.beanToMap(param, false, true);
                builder.append(result.entrySet().stream()
                        .map(entry -> entry.getKey() + PARAM_EQUAL_SEPARATE + entry.getValue())
                        .collect(Collectors.joining(PARAM_SEPARATE)));
            }
            return builder.toString();
        } catch (Exception e) {
            return new SimpleKey(params);
        }
    }

    public static String generate(String clsName, String methodName, String params) {
        StringBuilder sb = new StringBuilder();
        sb.append(clsName);
        sb.append(SEPARATE);
        sb.append(methodName);
        if (!StringUtils.isEmpty(params)) {
            sb.append(SEPARATE);
            sb.append(params);
        }
        return sb.toString();
    }
}
